package com.junjun.ssm.controller;

import com.junjun.ssm.dao.IUserDao;
import com.junjun.ssm.util.CacheUtil;

import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.concurrent.TimeUnit;

@RestController
public class UserController {
    @Autowired
    IUserDao userDao;
    @Autowired
    RedisTemplate<String,Object> redisTemplate;
    @Autowired
    RLock rLock;
    @GetMapping("userInfo/{age}/{score}")
    public Object userInfo(@PathVariable("age")int age,
                                     @PathVariable("score")int score) throws InterruptedException {

        if(!CacheUtil.bloomFilter.mightContain(String.valueOf(age))||!CacheUtil.bloomFilter.mightContain(String.valueOf(score))){
            return  null;
        }

      return this.cache(age,score);
    }

    public Object cache(int age,int score) throws InterruptedException {
        Object list=null;
        //用查询条件组装KEY
        String key=age+"_"+score;
        //判断缓存是否不存在
        if(!redisTemplate.hasKey(key)){
            //竞争锁
            Boolean bl=    rLock.tryLock(0,10,TimeUnit.SECONDS);
            if(bl){
                //去查询数据库
                 list=userDao.findAllByAgeAndScore(age,score);
                //放入缓存
                int hashCode=   key.hashCode();
                int num=  hashCode% CacheUtil.MAX_TIME;
                if(num<CacheUtil.MIN_TIME){
                    num=CacheUtil.MIN_TIME;
                }
                if(null==list){
                    redisTemplate.opsForValue().set(key, list, CacheUtil.MIN_TIME, TimeUnit.SECONDS);
                }else {
                    redisTemplate.opsForValue().set(key, list, num, TimeUnit.SECONDS);
                }
            }else {
                //没竞争到锁就休眠
                Thread.sleep(500);
                this.cache(age,score);
            }
        }else {
            //缓存存在
           list=redisTemplate.opsForValue().get(key);
        }
     return  list;
    }
}
